/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.anzix.osgi.jabberconsole.internal;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.eclipse.osgi.framework.console.CommandInterpreter;
import org.eclipse.osgi.framework.console.CommandProvider;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

/**
 *
 * @author elek
 */
public class CommandInterpreterImpl implements CommandInterpreter {

    String consoleStr;
    BundleContext bc;
    StringTokenizer tok;
    String cmdType;
    PrintWriter outputWriter;
    ByteArrayOutputStream output;

    public CommandInterpreterImpl(String consoleStr, BundleContext bc) {
        this.consoleStr = consoleStr;
        this.bc = bc;
        tok = new StringTokenizer(consoleStr, " ");
        cmdType = tok.nextToken();
        output = new ByteArrayOutputStream();
        outputWriter = new PrintWriter(output);
    }

    public String getOutput() {
        outputWriter.flush();
        outputWriter.close();
        return output.toString();
    }

    public String nextArgument() {
        if (tok == null || !tok.hasMoreElements()) {
            return null;
        }
        return tok.nextToken();
    }

    public Object execute() {
        return execute(cmdType);
    }

    public Object execute(String cmdType) {
        try {
            ServiceReference[] equinoxServRefs = bc.getServiceReferences("org.eclipse.osgi.framework.console.CommandProvider", null);
            if (equinoxServRefs != null) {
                Class[] parameterTypes = new Class[]{CommandInterpreter.class};

                for (int i = 0; i < equinoxServRefs.length; i++) {
                    ServiceReference serviceReference = equinoxServRefs[i];
                    CommandProvider service = (CommandProvider) bc.getService(serviceReference);
                    try {
                        Method method = service.getClass().getMethod("_" + cmdType, parameterTypes);
                        System.out.println(service.getClass().getName() + " " + method.getName());
                        Object[] parameters = new Object[]{this};
                        Object retval = method.invoke(service, parameters);
                        if (retval != null) {
                            System.out.println(retval);
                        }
                        return retval;
                    } catch (NoSuchMethodException ex) {
                        //keep finding
                    }
                }
            }

        } catch (Exception ex) {
            Logger.getLogger(CommandInterpreterImpl.class.getName()).log(Level.SEVERE, null, ex);
        }
        throw new IllegalArgumentException("No such command");
    }

    public void print(Object arg0) {
        outputWriter.print(arg0);

    }

    public void println() {
        outputWriter.println();
    }

    public void println(Object arg0) {
        System.out.println(arg0);
        outputWriter.println(arg0);

    }

    public void printStackTrace(Throwable arg0) {
        arg0.printStackTrace(outputWriter);
    }

    public void printDictionary(Dictionary dic, String arg1) {
        Enumeration elements = dic.elements();
        while (elements.hasMoreElements()) {
            println(elements.nextElement());
        }
    }

    public void printBundleResource(Bundle bundle, String arg1) {
        println("Bundle: " + bundle.getBundleId() + " " + bundle.getSymbolicName());
    }
}
